package com.yonyou.pmclouds.team.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoInsertMultiProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoUpdateProcessor;
import com.yonyou.pmclouds.basecom.bp.template.MultiInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleDeleteBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleUpdateBpTemplate;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.exception.ConcurrentOperationException;
import com.yonyou.pmclouds.basecom.lock.AutoReleaseLockUtil;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.project.entity.ProjectConst;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.team.entity.TeamEnterpriseVO;
import com.yonyou.pmclouds.team.entity.TeamMemberVO;
import com.yonyou.pmclouds.team.mapper.TeamEnterpriseMapper;
import com.yonyou.pmclouds.team.mapper.TeamMapper;
import com.yonyou.pmclouds.team.processor.TeamEntDeleteCheck;
import com.yonyou.pmclouds.team.processor.TeamEnterpriseInsertCheck;
import com.yonyou.pmclouds.team.rmiitf.TeamEnterpriseMaintain;
import com.yonyou.pmclouds.team.rmiitf.TeamMemberQuery;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.Map;

@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = TeamEnterpriseMaintain.class)
public class TeamEnterpriseMaintainImpl implements TeamEnterpriseMaintain {
    @Autowired
    private TeamEnterpriseMapper mapper;
    @Autowired
    private TeamMapper teamMapper;
    @Autowired
    private ProjectSimpleQuery projectSimpleQuery;
    @Autowired
    private TeamMemberQuery teamMemberQuery;

    @Override
    public String[] addEnterpriseToProject( String pkProject,TeamEnterpriseVO[] enterprises) throws BusinessException {
        if (ArrayUtils.isEmpty(enterprises)) {
            return null;
        }
        // lock
        if (!AutoReleaseLockUtil.addAutoReleaseLock(pkProject)) {
            throw new ConcurrentOperationException();
        }
//        ProjectVO project = projectSimpleQuery.queryProject(pkProject);
//        if (project.getProjectState() == ProjectConst.STATE_END) {
//            throw new BusinessException("已经结束的项目，不可再操作项目参与方！");
//        }
        for (TeamEnterpriseVO ent : enterprises) {
            ent.setPkProject(pkProject);
            ent.setPkTenant(RuntimeEnvironment.getTenantId());
        }
        MultiInsertBpTemplate<TeamEnterpriseVO> bp = new MultiInsertBpTemplate<>(mapper);
        // 校验项目下，企业的唯一性
        bp.addBeforeProcessor(new TeamEnterpriseInsertCheck(mapper));
        bp.addBeforeProcessor(new AuditInfoInsertMultiProcessor<TeamEnterpriseVO>());
        bp.insert(enterprises);
        String[] pks = new String[enterprises.length];
        for (int i = 0; i < enterprises.length; i++) {
            pks[i] = enterprises[i].getPkTeamEnt();
        }
        return pks;
    }

    @Override
    public String removeEnterpriseOfTeam(TeamEnterpriseVO enterprise) throws BusinessException {
        TeamEnterpriseVO[] ents = mapper.queryByIds(new String[]{enterprise.getPkTeamEnt()});
        if (ArrayUtils.isEmpty(ents)) {
            return null;
        }
        enterprise = ents[0];
        // lock
        if (!AutoReleaseLockUtil.addAutoReleaseLock(enterprise.getPkProject())) {
            throw new ConcurrentOperationException();
        }
        ProjectVO project = projectSimpleQuery.queryProject(enterprise.getPkProject());
        if (project.getProjectState() == ProjectConst.STATE_END) {
            throw new BusinessException("已经结束的项目，不可再操作项目参与方！");
        }
        SingleDeleteBpTemplate<TeamEnterpriseVO> bp = new SingleDeleteBpTemplate<>(mapper);
        //  校验团队成员是否移除完成
        bp.addBeforeProcessor(new TeamEntDeleteCheck(teamMapper));
        bp.delete(enterprise);
        return enterprise.getPkTeamEnt();
    }

    @Override
    public TeamEnterpriseVO[] updateEnterprise(TeamEnterpriseVO[] teamEnterpriseVOs) throws BusinessException{

        if(ArrayUtils.isEmpty(teamEnterpriseVOs))
            return new TeamEnterpriseVO[0];

        SingleUpdateBpTemplate<TeamEnterpriseVO> bp = new SingleUpdateBpTemplate<TeamEnterpriseVO>(mapper,new String[]{TeamEnterpriseVO.ENT_ROLE});
        bp.addBeforeProcessor(new AuditInfoUpdateProcessor<TeamEnterpriseVO>());
        for (TeamEnterpriseVO teamEnterpriseVO:
                teamEnterpriseVOs) {
            bp.update(teamEnterpriseVO) ;
        }

        updateMemberRole(teamEnterpriseVOs);

        return teamEnterpriseVOs;
    }

    /**
     * 更新成员角色
     * @param teamEnterpriseVOs
     * @throws BusinessException
     */
    private void updateMemberRole(TeamEnterpriseVO[] teamEnterpriseVOs) throws BusinessException {

        if(ArrayUtils.isEmpty(teamEnterpriseVOs))
            return;

        Map<String,TeamEnterpriseVO> pkAndEntMap = new HashMap<String,TeamEnterpriseVO>();
        for (TeamEnterpriseVO teamEnterpriseVO
                :teamEnterpriseVOs) {
            pkAndEntMap.put(teamEnterpriseVO.getPkEnterprise(),teamEnterpriseVO);
        }

        TeamMemberVO[] teamMemberVOs = teamMemberQuery.queryByProjectAndEnts(teamEnterpriseVOs[0].getPkProject(),pkAndEntMap.keySet().toArray(new String[0]));

        if(ArrayUtils.isEmpty(teamMemberVOs))
            return;

        SingleUpdateBpTemplate<TeamMemberVO> teamBp= new SingleUpdateBpTemplate<TeamMemberVO>(teamMapper,new String[]{TeamMemberVO.USER_ROLE});
        teamBp.addBeforeProcessor(new AuditInfoUpdateProcessor<TeamMemberVO>());

        for (TeamMemberVO memberVO :
                teamMemberVOs) {
            if(memberVO.getUserRole() != TeamMemberVO.UserRoleConst.ROLE_MANAGER){
                memberVO.setUserRole(pkAndEntMap.get(memberVO.getPkEnterprise()).getEntRole());
                teamBp.update(memberVO);
            }
        }
    }

    @Override
    public void updateEnterpriseForProject(String pkProject, TeamEnterpriseVO[] insertEnterpriseVOs, TeamEnterpriseVO[] updateEnterpriseVOs, TeamEnterpriseVO[] deleteEnterpriseVOs) throws BusinessException {

        if(ArrayUtils.isNotEmpty(updateEnterpriseVOs)){
            this.updateEnterprise(updateEnterpriseVOs);
        }

        if(ArrayUtils.isNotEmpty(deleteEnterpriseVOs)){
            for (TeamEnterpriseVO deleteEnterpriseVO:
                    deleteEnterpriseVOs) {
                this.removeEnterpriseOfTeam(deleteEnterpriseVO);
            }
        }

        if(ArrayUtils.isNotEmpty(insertEnterpriseVOs)){
            this.addEnterpriseToProject(pkProject,insertEnterpriseVOs);
        }

    }
}
